using System;
using System.Text;
using System.Windows.Forms;
using BanZuiCloudControlAgent.Utils.Logging;

namespace BanZuiCloudControlAgent.Utils.Exceptions
{
    /// <summary>
    /// 全局异常处理器，用于统一处理应用程序中的异常
    /// </summary>
    public class ExceptionHandler
    {
        private readonly Logger _logger;
        private readonly bool _showMessageBox;

        /// <summary>
        /// 初始化ExceptionHandler类的新实例
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="showMessageBox">是否显示消息框</param>
        public ExceptionHandler(Logger logger, bool showMessageBox = true)
        {
            _logger = logger ?? LogManager.GetLogger(nameof(ExceptionHandler));
            _showMessageBox = showMessageBox;
        }

        /// <summary>
        /// 初始化全局异常处理系统
        /// </summary>
        public static void Initialize()
        {
            SetupGlobalExceptionHandlers();
        }

        /// <summary>
        /// 处理异常
        /// </summary>
        /// <param name="ex">要处理的异常</param>
        /// <param name="source">异常来源</param>
        /// <returns>是否为致命错误</returns>
        public bool Handle(Exception ex, string source = null)
        {
            if (ex == null)
            {
                return false;
            }

            bool isFatal = false;

            // 根据异常类型进行特殊处理
            if (ex is BanZuiException banZuiEx)
            {
                isFatal = HandleBanZuiException(banZuiEx, source);
            }
            else
            {
                // 处理标准异常
                isFatal = HandleStandardException(ex, source);
            }

            return isFatal;
        }

        /// <summary>
        /// 处理BanZuiException类型的异常
        /// </summary>
        /// <param name="ex">要处理的BanZuiException异常</param>
        /// <param name="source">异常来源</param>
        /// <returns>是否为致命错误</returns>
        private bool HandleBanZuiException(BanZuiException ex, string source)
        {
            string logMessage = FormatExceptionMessage(ex, source);

            // 根据异常类型选择日志级别
            if (ex.IsFatal)
            {
                _logger.Fatal(logMessage, ex);
            }
            else
            {
                _logger.Error(logMessage, ex);
            }

            // 显示消息框（如果需要）
            if (_showMessageBox)
            {
                ShowErrorMessageBox(ex, source);
            }

            return ex.IsFatal;
        }

        /// <summary>
        /// 处理标准异常
        /// </summary>
        /// <param name="ex">要处理的标准异常</param>
        /// <param name="source">异常来源</param>
        /// <returns>是否为致命错误</returns>
        private bool HandleStandardException(Exception ex, string source)
        {
            string logMessage = FormatExceptionMessage(ex, source);

            // 对于标准异常，使用Error级别记录日志
            _logger.Error(logMessage, ex);

            // 显示消息框（如果需要）
            if (_showMessageBox)
            {
                ShowErrorMessageBox(ex, source);
            }

            return false;
        }

        /// <summary>
        /// 格式化异常消息
        /// </summary>
        /// <param name="ex">异常</param>
        /// <param name="source">异常来源</param>
        /// <returns>格式化后的异常消息</returns>
        private string FormatExceptionMessage(Exception ex, string source)
        {
            StringBuilder sb = new StringBuilder();

            if (!string.IsNullOrEmpty(source))
            {
                sb.Append($"[{source}] ");
            }

            if (ex is BanZuiException banZuiEx)
            {
                sb.Append($"[{banZuiEx.ErrorCode}] {banZuiEx.Module}: {banZuiEx.Message}");
            }
            else
            {
                sb.Append($"{ex.GetType().Name}: {ex.Message}");
            }

            return sb.ToString();
        }

        /// <summary>
        /// 显示错误消息框
        /// </summary>
        /// <param name="ex">异常</param>
        /// <param name="source">异常来源</param>
        private void ShowErrorMessageBox(Exception ex, string source)
        {
            try
            {
                string title;
                string message;
                MessageBoxIcon icon;

                if (ex is BanZuiException banZuiEx)
                {
                    title = banZuiEx.IsFatal ? "严重错误" : "错误";
                    message = FormatMessageBoxText(banZuiEx, source);
                    icon = banZuiEx.IsFatal ? MessageBoxIcon.Stop : MessageBoxIcon.Error;
                }
                else
                {
                    title = "错误";
                    message = FormatMessageBoxText(ex, source);
                    icon = MessageBoxIcon.Error;
                }

                MessageBox.Show(message, title, MessageBoxButtons.OK, icon);
            }
            catch
            {
                // 忽略显示消息框时的异常
            }
        }

        /// <summary>
        /// 格式化消息框文本
        /// </summary>
        /// <param name="ex">异常</param>
        /// <param name="source">异常来源</param>
        /// <returns>格式化后的消息框文本</returns>
        private string FormatMessageBoxText(Exception ex, string source)
        {
            StringBuilder sb = new StringBuilder();

            if (!string.IsNullOrEmpty(source))
            {
                sb.AppendLine($"来源: {source}");
                sb.AppendLine();
            }

            if (ex is BanZuiException banZuiEx)
            {
                sb.AppendLine($"错误代码: {banZuiEx.ErrorCode}");
                sb.AppendLine($"模块: {banZuiEx.Module}");
                sb.AppendLine();
                sb.AppendLine($"错误信息: {banZuiEx.Message}");

                // 添加特定异常类型的额外信息
                if (ex is NetworkException networkEx)
                {
                    sb.AppendLine($"错误类型: {networkEx.ErrorType}");
                }
                else if (ex is EmqxException emqxEx && !string.IsNullOrEmpty(emqxEx.Topic))
                {
                    sb.AppendLine($"错误类型: {emqxEx.ErrorType}");
                    sb.AppendLine($"主题: {emqxEx.Topic}");
                }
                else if (ex is QQException qqEx && !string.IsNullOrEmpty(qqEx.QQAccount))
                {
                    sb.AppendLine($"错误类型: {qqEx.ErrorType}");
                    sb.AppendLine($"QQ账号: {qqEx.QQAccount}");
                }
                else if (ex is ConfigurationException configEx && !string.IsNullOrEmpty(configEx.ConfigKey))
                {
                    sb.AppendLine($"错误类型: {configEx.ErrorType}");
                    sb.AppendLine($"配置键: {configEx.ConfigKey}");
                }
                else if (ex is TaskException taskEx && !string.IsNullOrEmpty(taskEx.TaskId))
                {
                    sb.AppendLine($"错误类型: {taskEx.ErrorType}");
                    sb.AppendLine($"任务ID: {taskEx.TaskId}");
                }
            }
            else
            {
                sb.AppendLine($"错误类型: {ex.GetType().Name}");
                sb.AppendLine();
                sb.AppendLine($"错误信息: {ex.Message}");
            }

            // 添加内部异常信息
            if (ex.InnerException != null)
            {
                sb.AppendLine();
                sb.AppendLine($"内部错误: {ex.InnerException.Message}");
            }

            return sb.ToString();
        }

        /// <summary>
        /// 设置全局未处理异常处理器
        /// </summary>
        public static void SetupGlobalExceptionHandlers()
        {
            // 设置UI线程未捕获异常处理
            Application.ThreadException += (sender, e) =>
            {
                var handler = new ExceptionHandler(LogManager.GetLogger("UnhandledException"));
                handler.Handle(e.Exception, "UI线程");
            };

            // 设置非UI线程未捕获异常处理
            AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
            {
                var handler = new ExceptionHandler(LogManager.GetLogger("UnhandledException"));
                handler.Handle(e.ExceptionObject as Exception, "非UI线程");
            };
        }
    }
} 